﻿using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Runtime;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Autodesk.AutoCAD.Geometry;
using System.IO;

using IFoxCAD.Cad;
using System.Reflection;
using System.Globalization;
//using System.Globalization;
//using Autodesk.AutoCAD.GraphicsInterface;

namespace CAD.Service
{
    public class _ExtensionTest_
    {
        public static string assemblyPath = Assembly.GetExecutingAssembly().Location;
        //public static string assemblyDir = Path.GetDirectoryName(assemblyPath) + "\\";
        public static string assemblyDir = @"D:\WORKSPACE\CODE_CAD\CAD.Demo\bin\Debug\";

        //Assembly assemblyBase = Assembly.LoadFrom($"{assemblyDir}IFox.Basal.dll");
        //Assembly assemblyAcad = Assembly.LoadFrom($"{assemblyDir}IFox.CAD.ACAD.dll");


        // 块定义
        [CommandMethod(nameof(Test_BlockDef))]
        public void Test_BlockDef()
        {
            using (DBTrans tr = new DBTrans())
            {
                // var line = new Line(new Point3d(0, 0, 0), new Point3d(1, 1, 0));
                tr.BlockTable.Add("testt",
                    btr =>
                    {
                        btr.Origin = new Point3d(0, 0, 0);
                    },
                    () => // 图元
                    {
                        return new List<Entity> { new Line(new Point3d(0, 0, 0), new Point3d(1, 1, 0)) };
                    },
                    () => // 属性定义
                    {
                        var id1 = new AttributeDefinition() { Position = new Point3d(0, 0, 0), Tag = "start", Height = 0.2 };
                        var id2 = new AttributeDefinition() { Position = new Point3d(1, 1, 0), Tag = "end", Height = 0.2 };
                        return new List<AttributeDefinition> { id1, id2 };
                    }
                );

                tr.CurrentSpace.InsertBlock(new Point3d(10, 10, 0), "testt" );

                // ObjectId objectId = tr.BlockTable.Add("a");// 新建块
                // objectId.GetObject<BlockTableRecord>().AddEntity();// 测试添加空实体
                tr.BlockTable.Add("test1",
                btr =>
                {
                    btr.Origin = new Point3d(0, 0, 0);
                },
                () =>
                { 
                     var line = new Line(new Point3d(0, 0, 0), new Point3d(1, 1, 0));
                    //var acText = (new  TextInfo("123", Point3d.Origin, AttachmentPoint.BaseLeft))
                    //            .AddDBTextToEntity();

                    return new List<Entity> { line };
                });
            }
        }

        [CommandMethod(nameof(iterateEntity))]
        public void iterateEntity()
        {

            using (DBTrans tr = new DBTrans())
            {
                tr.CurrentSpace.ForEach(id =>
                {
                    var ent = id.GetObject<Entity>();
                    //如果要修改图元时var entity1 = id.GetObject<Entity>(OpenMode.ForWrite);
                    ent?.GetRXClass().DxfName.Print();
                    Env.Print("\n ");
                    Env.Print("\nDXF 名称:    " + ent?.GetRXClass().Name);
                    //AcDbLine,AcDbPolyline,AcDbText
                    Env.Print("\n图元名称:    " + ent?.GetType().Name);
                    //Line,Polyline,DBText
                    Env.Print("\nObjectID:    " + ent?.ToString());
                    Env.Print("\nHandle:      " + ent?.Handle.ToString());
                    if (ent is Line acdbLine)//如果ent是直线，转换为直线变量cdbLine
                    {
                        Env.Print("\nacDbLinet长度为： ");
                        //var txt = acdbLine.GetProperty("Length");//取得直度长度属性
                        var txt = acdbLine.Length;  // 这么写就可以了
                        txt.Print();
                    }
                    Env.Print("\n********************\n");
                });
            }

        }

        [CommandMethod("AddSplineX")]
        public static void AddSplineX()
        {
            Database database = HostApplicationServices.WorkingDatabase;
            database.GetEditor().WriteMessage($"\n-------{assemblyPath}-----\n");
            database.GetEditor().WriteMessage("\n---------start----------\n");
            // Define the fit points for the spline
            Point3dCollection ptColl = new Point3dCollection();
            ptColl.Add(new Point3d(0, 0, 0));
            ptColl.Add(new Point3d(5, 5, 0));
            ptColl.Add(new Point3d(10, 0, 0));

            // Get a 3D vector from the point (0.5,0.5,0)
            Vector3d vecTan = new Point3d(0.5, 0.5, 0).GetAsVector();
            // Create a spline through (0, 0, 0), (5, 5, 0), and (10, 0, 0) with a
            Spline acSpline = new Spline(ptColl, vecTan, vecTan, 3, 0.0);
            using (var tr = new DBTrans())
            {
                tr.ModelSpace.AddEntity(acSpline);
            };

        }

        [CommandMethod("IFoxCADAddTest1")]
        public static void IFoxCADAddTest1()
        {

            Database database = HostApplicationServices.WorkingDatabase;
            database.GetEditor().WriteMessage($"\n-------{assemblyPath}-----\n");
            database.GetEditor().WriteMessage("\n---------start----------\n");



            Polyline polyline = new Polyline();
            polyline.AddVertexAt(0, new Point2d(0, 0), 0, 3, 1);
            polyline.AddVertexAt(1, new Point2d(100, -10), -Math.PI * 0.25, 0, 0);
            polyline.AddVertexAt(2, new Point2d(300, 100), 0, 0, 0);
            polyline.Closed = false;

            using (var tr = new DBTrans())
            {
                tr.ModelSpace.AddEntity(polyline);

            };


        }

        [CommandMethod("CadDbText")]
        public static void CadDbText()
        {
            //当前选项卡文档
            Document document = Application.DocumentManager.MdiActiveDocument;
            Database database = HostApplicationServices.WorkingDatabase;

            //编辑器
            Editor editor = document.Editor;
            editor.WriteMessage($"\n ====================running CadDbText====================== \n ");//命令行文字

            //创建文字
            DBText text = new DBText();
            text.Rotation = 90;
            text.TextString = "first dbtext vs c#";
            text.Position = new Autodesk.AutoCAD.Geometry.Point3d(0, 0, 0);
            text.Height = 300;
            text.Color = Autodesk.AutoCAD.Colors.Color.FromRgb(1, 122, 1);

            //SetFocus(document.Window.Handle);//提前调用
            //执行代码  

            database.AddToModelSpace(text, true);

        }


        [CommandMethod("EditEntity")]
        public static void EditEntity()
        {
            Database database = HostApplicationServices.WorkingDatabase;
            Entity entity = database.GetEditor().SelectEntity()[0];
            if (entity != null && entity is Circle)
            {
                Circle circle = entity as Circle;
                if (circle != null)
                {
                    using (Transaction transaction = database.TransactionManager.StartTransaction())
                    {
                        circle = (Circle)entity.ObjectId.GetObject(OpenMode.ForWrite);
                        circle.Radius = 10;
                        transaction.Commit();
                    }
                }

                var circle1 = circle.Clone() as Circle;
                circle1.Radius = 100;
                database.AddToModelSpace(circle1, true);
            }
        }


        [CommandMethod("AddPolyline")]
        public static void AddPolyline()
        {
            Database database = HostApplicationServices.WorkingDatabase;
            Polyline polyline = new Polyline();
            polyline.AddVertexAt(0, new Point2d(0, 0), 0, 3, 1);
            polyline.AddVertexAt(1, new Point2d(100, -10), -Math.PI * 0.25, 0, 0);
            polyline.AddVertexAt(2, new Point2d(300, 100), 0, 0, 0);
            polyline.Closed = false;

            // database.AddToModelSpace(polyline, true);
            database.AttachEntity(polyline, true);

        }


        [CommandMethod("TransformEntity")]
        public static void TransformEntity()
        {
            Database database = HostApplicationServices.WorkingDatabase;
            var ents = database.GetEditor().SelectEntity();
            if (ents.Count() == 0) return;

            Entity entity = ents[0];

            Action action = new Action(() =>
            {
                entity = (Entity)entity.ObjectId.GetObject(OpenMode.ForWrite);
                //Matrix3d translate = Matrix3d.Displacement(new Vector3d(10, 20, 10));
                Matrix3d rotation = Matrix3d.Rotation(Math.PI * 0.2, Vector3d.ZAxis, Point3d.Origin);
                //entity = null;
                entity.TransformBy(rotation);
            });
            action = action.BuildTransaction(database).BuildDocumentLock(database);
            //database.RunTransaction(action);
            action.Invoke();


        }


        [CommandMethod("GetBlock")]
        public static void GetBlock()
        {
            Database database = HostApplicationServices.WorkingDatabase;
            var ents = database.SelectEntity<BlockReference>();
            if (ents.Count() == 0) return;
            BlockReference block = ents[0];

            string name = block.Name;
            double ro = block.Rotation;
            var sc = block.ScaleFactors;
            var pnt3d = block.Position;
            var btr = block.BlockTableRecord;

            Action action = new Action(() =>
            {
                //(BlockReference)block.ObjectId.GetObject(OpenMode.ForWrite);
                var blockRef = block.OpenInMode<BlockReference>(OpenMode.ForWrite, true, true);
                blockRef.Rotation = Math.PI * 0.5;

                //图形爆破
                DBObjectCollection dbObjectCollection = new DBObjectCollection();
                block.Explode(dbObjectCollection);
                foreach (Entity dbObject in dbObjectCollection)
                {

                }
            });
            action = action.BuildTransaction(database);
            action.Invoke();
        }

        [CommandMethod("AttribBlock")]
        public static void AttribBlock()
        {
            Database database = HostApplicationServices.WorkingDatabase;
            var ents = database.SelectEntity<BlockReference>();
            if (ents.Count() == 0) return;
            BlockReference blockRef = ents[0];


            Dictionary<string, string> pairs = new Dictionary<string, string>();
            Action action = new Action(() =>
            {
                //blockRef = (BlockReference)blockRef.ObjectId.GetObject(OpenMode.ForWrite);
                blockRef = blockRef.OpenInMode<BlockReference>(OpenMode.ForWrite, true, true);

                foreach (ObjectId blockAttrib in blockRef.AttributeCollection)
                {
                    AttributeReference attrRef = blockAttrib.OpenInMode<AttributeReference>(OpenMode.ForWrite, true, true);
                    if (attrRef.IsErased)
                    {
                        continue;
                    }
                    pairs.Add(attrRef.Tag, attrRef.TextString);
                    attrRef.TextString = "changed attrib";
                    database.GetEditor().WriteMessage($"\n{attrRef.Tag}\t{attrRef.TextString}\n");
                }

            });
            action = action.BuildTransaction(database);
            action.Invoke();
        }


        /// <summary>
        /// 动态块
        /// </summary>
        [CommandMethod("DynamicBlock")]
        public static void DynamicBlock()
        {
            Database database = HostApplicationServices.WorkingDatabase;
            var ents = database.SelectEntity<BlockReference>();
            if (ents.Count() == 0) return;
            BlockReference blockRef = ents[0];


            Dictionary<string, string> pairs = new Dictionary<string, string>();
            Action action = new Action(() =>
            {
                //blockRef = (BlockReference)blockRef.ObjectId.GetObject(OpenMode.ForWrite);
                blockRef = blockRef.OpenInMode<BlockReference>(OpenMode.ForWrite, true, true);

                if (!blockRef.IsDynamicBlock) { return; }
                foreach (DynamicBlockReferenceProperty item in blockRef.DynamicBlockReferencePropertyCollection)
                {
                    if (item.PropertyName == "width")
                    {
                        item.Value = (object)300d;
                    }
                    if (item.PropertyName == "DEEP")
                    {
                        item.Value = (object)100d;
                    }
                    if (item.PropertyName == "visable")
                    {
                        var names = item.GetAllowedValues();//
                        item.Value = names[0];
                    }
                }

            });
            action = action.BuildTransaction(database);
            action.Invoke();
        }




        [CommandMethod("AddTable")]
        public void AddTable()
        {
            Database database = HostApplicationServices.WorkingDatabase;

            Table table = new Table();
            table.SetSize(3, 5);
            table.SetRowHeight(100);
            table.SetColumnWidth(300);
            table.Position = new Point3d(100, 100, 100);
            table.Cells[0, 0].TextString = "title";
            table.Cells[0, 0].TextHeight = 80;
            database.AttachEntity(table, true);
        }

        [CommandMethod("AddDwgFile")]
        public void AddDwgFile()
        {
            string file = @"D:\WORKSPACE\DOC\QC\图例拆分\感应壁灯.dwg";
            if (!File.Exists(file)) { return; }
            Database database = HostApplicationServices.WorkingDatabase;
            Database newDB = new Database(false, true);
            newDB.ReadDwgFile(file, FileShare.Read, true, null);
            string blockName = "22";
            ObjectId objectId = database.Insert(blockName, newDB, true);
            BlockReference blockReference = new BlockReference(Point3d.Origin, objectId);
            newDB.Dispose();

            DBObjectCollection dbObjectCollection = new DBObjectCollection();
            blockReference.Explode(dbObjectCollection);

            List<Entity> entitys = new List<Entity>();
            foreach (Entity entity in dbObjectCollection) { entitys.Add(entity); }
            database.AttachEntity(entitys, true);
            //database.AttachEntity(blockReference, true);

        }



    }
}
